package com.xdcplus.web.service.bd.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.xdcplus.core.utils.BeanUtils;
import com.xdcplus.exceptions.XdcWebException;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.mom.enums.ResponseEnum;
import com.xdcplus.mom.utils.ResponseUtils;
import com.xdcplus.mp.service.impl.BaseServiceImpl;
import com.xdcplus.mp.utils.PageableUtils;
import com.xdcplus.mp.utils.PropertyUtils;
import com.xdcplus.pager.vo.PageVO;
import com.xdcplus.system.api.AuthRemote;
import com.xdcplus.web.common.pojo.dto.bd.BdClassGroupDTO;
import com.xdcplus.web.common.pojo.dto.bd.BdClassGroupFilterDTO;
import com.xdcplus.web.common.pojo.dto.pm.PmShiftPlanGroupFilterDTO;
import com.xdcplus.web.common.pojo.entity.bd.BdClassGroup;
import com.xdcplus.web.common.pojo.query.bd.BdClassGroupQuery;
import com.xdcplus.web.common.pojo.vo.bd.BdClassGroupVO;
import com.xdcplus.web.common.pojo.vo.pm.PmShiftPlanGroupVO;
import com.xdcplus.web.mapper.bd.BdClassGroupMapper;
import com.xdcplus.web.service.bd.BdClassGroupService;
import com.xdcplus.web.service.bd.BdClassGroupUserService;
import com.xdcplus.web.service.bd.BdFactoryService;
import com.xdcplus.web.service.pm.PmShiftPlanGroupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * 班组表(BdClassGroup)表服务实现类
 *
 * @author Fish.Fei
 * @since 2023-01-31 16:57:35
 */
@Slf4j
@Service("bdClassGroupService")
public class BdClassGroupServiceImpl extends BaseServiceImpl<BdClassGroupMapper, BdClassGroup, BdClassGroup, BdClassGroupVO> implements BdClassGroupService {

    @Autowired
    protected BdClassGroupMapper bdClassGroupMapper;

    @Autowired
    protected BdFactoryService bdFactoryService;

    @Autowired
    protected AuthRemote authRemote;

    @Autowired
    protected PmShiftPlanGroupService pmShiftPlanGroupService;

    @Autowired
    protected BdClassGroupUserService bdClassGroupUserService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean saveBdClassGroup(BdClassGroupDTO bdClassGroupDTO) {
        checkCodeIsExists(bdClassGroupDTO.getGroupCode(),null);
        checkNameIsExists(bdClassGroupDTO.getGroupName(),null);
        BdClassGroup bdClassGroup = new BdClassGroup();
        BeanUtil.copyProperties(bdClassGroupDTO, bdClassGroup);
        bdClassGroup.setCreatedTime(new Timestamp(DateUtil.current()));
        
        return this.save(bdClassGroup);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean updateBdClassGroup(BdClassGroupDTO bdClassGroupDTO) {

        BdClassGroup bdClassGroup = this.getById(bdClassGroupDTO.getId());
        if (ObjectUtil.isNull(bdClassGroup)) {
            log.error("updateBdClassGroup() The BdClassGroup does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        checkCodeIsExists(bdClassGroupDTO.getGroupCode(),bdClassGroupDTO.getId());
        checkNameIsExists(bdClassGroupDTO.getGroupName(),bdClassGroupDTO.getId());

        BeanUtil.copyProperties(bdClassGroupDTO, bdClassGroup);
        bdClassGroup.setUpdatedUser(bdClassGroupDTO.getUpdatedUser());
        bdClassGroup.setUpdatedTime(new Timestamp(DateUtil.current()));

        return this.updateById(bdClassGroup);
    }

    @Override
    public Boolean saveOrUpdateBatch(List<BdClassGroup> bdClassGroupList) {

        bdClassGroupList.forEach(bdClassGroup -> {
            BdClassGroup bdClassGroupParam = new BdClassGroup();
            bdClassGroupParam.setId(bdClassGroup.getId());
            if (ObjectUtil.isNotNull(bdClassGroup.getId())) {
                bdClassGroup.setId(bdClassGroup.getId());
                bdClassGroup.setUpdatedTime(new Timestamp(DateUtil.current()));
                LambdaUpdateWrapper<BdClassGroup> lambdaUpdate = Wrappers.lambdaUpdate();
                lambdaUpdate.eq(BdClassGroup::getId, bdClassGroup.getId());
                update(bdClassGroup, lambdaUpdate);
            } else {
                bdClassGroup.setCreatedTime(new Timestamp(DateUtil.current()));
                save(bdClassGroup);
            }
        });
        return true;
    }

    @Override
    public Boolean saveOrUpdateBatchByDTOList(List<BdClassGroupDTO> bdClassGroupDTOList) {

        List<BdClassGroup> bdClassGroupList = BeanUtils.copyProperties(bdClassGroupDTOList, BdClassGroup.class);
        return saveOrUpdateBatch(bdClassGroupList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteBdClassGroupLogical(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        BdClassGroup bdClassGroup = this.getById(id);

        if (ObjectUtil.isNull(bdClassGroup)) {
            log.error("deleteBdClassGroup() The BdClassGroup does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        //判断排班计划班组是否被引用，引用无法删除
        //删除班组下所有用户关系
        PmShiftPlanGroupFilterDTO pmShiftPlanGroupFilterDTO = new PmShiftPlanGroupFilterDTO();
        pmShiftPlanGroupFilterDTO.setClassGroupIdFk(id);
        List<PmShiftPlanGroupVO> pmShiftPlanGroupVOS = pmShiftPlanGroupService.queryPmShiftPlanGroupVOList(pmShiftPlanGroupFilterDTO);
        Assert.isTrue(CollectionUtil.isEmpty(pmShiftPlanGroupVOS),ResponseEnum.BD_CLASS_GROUP_DELETE_FAILD.getMessage());

        bdClassGroupUserService.deleteBdClassGroupUserByClassGroupId(id);

        return this.removeById(id);
    }
    
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteBdClassGroupByIds(String ids) {
        Assert.notNull(ids, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());
		List<String> idList = Arrays.asList(ids.split(","));
		if(CollectionUtil.isEmpty(idList)){
           throw new XdcWebException(ResponseEnum.ERROR);
       }
		idList.forEach(id->{
			BdClassGroup bdClassGroup = this.getById(id);
			if (ObjectUtil.isNull(bdClassGroup)) {
				log.error("deleteBdClassGroup() The BdClassGroup does not exist or has been deleted");
				throw new XdcWebException(ResponseEnum.ERROR);
			}
		});
		
        return this.removeByIds(idList);
    }

    private List<BdClassGroup> queryBdClassGroupList(BdClassGroupFilterDTO bdClassGroupFilterDTO) {
        BdClassGroupQuery bdClassGroupQuery = BeanUtil.copyProperties(bdClassGroupFilterDTO, BdClassGroupQuery.class);

        return bdClassGroupMapper.queryBdClassGroup(bdClassGroupQuery);
    }

    @Override
    public List<BdClassGroupVO> queryBdClassGroupVOList(BdClassGroupFilterDTO bdClassGroupFilterDTO) {
        return this.objectConversion(queryBdClassGroupList(bdClassGroupFilterDTO));
    }

    @Override
    public PageVO<BdClassGroupVO> queryBdClassGroup(BdClassGroupFilterDTO bdClassGroupFilterDTO) {
        PageVO<BdClassGroupVO> pageVO = new PageVO<>();

        if (bdClassGroupFilterDTO.getCurrentPage() > NumberConstant.ZERO) {
            PageableUtils.basicPage(bdClassGroupFilterDTO.getCurrentPage(), bdClassGroupFilterDTO.getPageSize(),
                    bdClassGroupFilterDTO.getOrderType(), bdClassGroupFilterDTO.getOrderField());
        }

        List<BdClassGroup> bdClassGroupList = queryBdClassGroupList(bdClassGroupFilterDTO);

        PageInfo<BdClassGroup> pageInfo = new PageInfo<>(bdClassGroupList);
        PropertyUtils.copyProperties(pageInfo, pageVO, this.objectConversion(bdClassGroupList));

        return pageVO;
    }

    @Override
    public BdClassGroupVO queryBdClassGroupById(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        return this.objectConversion(this.getById(id));
    }


    @Override
    public BdClassGroupVO objectConversion(BdClassGroup s) {
        BdClassGroupVO bdClassGroupVO = super.objectConversion(s);
        bdClassGroupVO.setFactoryVO(bdFactoryService.queryBdFactoryById(bdClassGroupVO.getWorkshopId()));
        if(bdClassGroupVO.getDirectorId()!=null){
            bdClassGroupVO.setUserInfoVO(ResponseUtils.getResponse(authRemote.queryUserInfoById(bdClassGroupVO.getDirectorId())));
        }

        return bdClassGroupVO;
    }

    @Override
    public List<BdClassGroupVO> objectConversion(List<BdClassGroup> sList) {
        if (!CollectionUtil.isNotEmpty(sList)) {
            return null;
        } else {
            List<BdClassGroupVO> tList = new ArrayList();
            Iterator var3 = sList.iterator();

            while(var3.hasNext()) {
                BdClassGroup s = (BdClassGroup)var3.next();
                BdClassGroupVO t = this.objectConversion(s);
                Optional.ofNullable(t).ifPresent(tList::add);
            }

            return tList;
        }
    }

    /**
     * 检验Code是否存在
     */
    private void checkCodeIsExists(String code,Long id){
        BdClassGroup bdClassGroup = bdClassGroupMapper.selectOne(new QueryWrapper<BdClassGroup>().eq("GROUP_CODE", code));

        if(bdClassGroup==null || (id!=null && bdClassGroup.getId().equals(id))){
            return;
        }
        throw new XdcWebException(ResponseEnum.CODE_ALREADY_EXISTS);
    }

    /**
     * 检验Name是否存在
     */
    private void checkNameIsExists(String name,Long id){
        BdClassGroup bdClassGroup = bdClassGroupMapper.selectOne(new QueryWrapper<BdClassGroup>().eq("GROUP_NAME", name));

        if(bdClassGroup==null || (id!=null && bdClassGroup.getId().equals(id))){
            return;
        }
        throw new XdcWebException(ResponseEnum.NAME_ALREADY_EXISTS);
    }

}
